<?php

require_once 'BancoDeDados.php';
require_once 'Usuario.php';
require_once 'Permissao.php';

/**
 * Recurso Grupo
 */
class Grupo {

    private $cod_grupo;
    private $descricao;
    private $usuarios = array();
    private $permissoes = array();
    private $vinculado;

    public function &getCod_grupo() {
        return $this->cod_grupo;
    }

    public function setCod_grupo(&$cod_grupo) {
        $this->cod_grupo = &$cod_grupo;
    }

    public function &getDescricao() {
        return $this->descricao;
    }

    public function setDescricao(&$descricao) {
        $this->descricao = &$descricao;
    }

    public function &listarUsuarios() {
        return $this->usuarios;
    }

    public function setLogins(&$usuarios) {
        $this->usuarios = &$usuarios;
    }

    public function setPermissoes(&$permissoes) {
        $this->permissoes = &$permissoes;
    }

    public function &listarPermissoes() {
        return $this->permissoes;
    }

    public function &isVinculado() {
        return $this->vinculado;
    }

    private function setVinculado(&$vinculado) {
        $this->vinculado = &$vinculado;
    }

    public function cadastrar() {
        if ($this->validar() != 1) {
            throw new Exception("Grupo existente");
        }
        $banco = BancoDeDados::getInstance();
        $link = $banco->getLink();
        $stmt = $link->prepare('insert into grupo (descricao) values(?)');
        $result = $link->execute($stmt, array($this->descricao));
        if (DB::isError($result)) {
            $link->rollBack();
            throw new Exception($result->getMessage());
        }
        $link->commit();
    }

    public function alterar() {
        if ($this->validar() != 1) {
            throw new Exception("Grupo existente");
        }
        $banco = BancoDeDados::getInstance();
        $link = $banco->getLink();
        $stmt = $link->prepare('update grupo set descricao = ? where cod_grupo = ?');
        $result = $link->execute($stmt, array($this->descricao, $this->cod_grupo));
        if (DB::isError($result)) {
            $link->rollBack();
            throw new Exception($result->getMessage());
        }
        $link->commit();
    }

    public function alterarCampo(&$campo_id, &$campo_valor) {
        if ($campo_id == 'descricao_consulta') {
            $this->descricao = &$campo_valor;
            $campo_id = 'descricao';
            if ($this->validar() != 1) {
                throw new Exception("Grupo existente");
            }
        }
        $banco = BancoDeDados::getInstance();
        $link = $banco->getLink();
        $stmt = $link->prepare('update grupo set ' . $campo_id . ' = ? where cod_grupo = ?');
        $result = $link->execute($stmt, array($campo_valor, $this->cod_grupo));
        if (DB::isError($result)) {
            $link->rollBack();
            throw new Exception($result->getMessage());
        }
        $link->commit();
    }

    public function excluir() {
        $banco = BancoDeDados::getInstance();
        $link = $banco->getLink();
        $stmt = $link->prepare('delete from grupo where cod_grupo = ?');
        $result = $link->execute($stmt, array($this->cod_grupo));
        if (DB::isError($result)) {
            $link->rollBack();
            throw new Exception($result->getMessage());
        }
        $link->commit();
    }

    public static function listar() {
        $banco = BancoDeDados::getInstance();
        $result = $banco->getLink()->query('select * from grupo');
        if (DB::isError($result)) {
            throw new Exception($result->getMessage());
        }
        $resultado = array();
        while ($result->fetchInto($row)) {
            $grupo = new Grupo();
            $grupo->setCod_grupo($row['cod_grupo']);
            $grupo->setDescricao($row['descricao']);
            $resultado[] = &$grupo;
            unset($grupo);
        }
        return $resultado;
    }

    public static function consultar(&$cod_grupo) {
        $banco = BancoDeDados::getInstance();
        $result = $banco->getLink()->query('select * from grupo where cod_grupo = ?', array($cod_grupo));
        if (DB::isError($result)) {
            throw new Exception($result->getMessage());
        }
        if ($result->numRows() == 0) {
            throw new Exception("Grupo inexistente");
        } elseif ($result->numRows() > 1) {
            throw new Exception("Mais de um Grupo com o mesmo identificador, informe ao administrador");
        }
        $result->fetchInto($row);
        $grupo = new Grupo();
        $grupo->setCod_grupo($row['cod_grupo']);
        $grupo->setDescricao($row['descricao']);
        $grupo->setLogins(Usuario::listar($row['cod_grupo']));
        $grupo->setPermissoes(Permissao::listar($row['cod_grupo']));
        $grupo->setVinculado($grupo->verificarVinculacao());
        return $grupo;
    }

    private function validar() {
        $banco = BancoDeDados::getInstance();
        $result = $banco->getLink()->query('select cod_grupo from grupo where descricao = ?', array($this->descricao));
        if (DB::isError($result)) {
            throw new Exception($result->getMessage());
        }
        if ($result->numRows() > 0) {
            return 0;
        }
        return 1;
    }

    private function verificarVinculacao() {
        $banco = BancoDeDados::getInstance();
        $result = $banco->getLink()->query('select cod_grupo from usuario where cod_grupo = ?', array($this->cod_grupo));
        if (DB::isError($result)) {
            throw new Exception($result->getMessage());
        }
        if ($result->numRows() > 0) {
            return 1;
        }
        return 0;
    }

    public function cadastrarUsuario(&$nome, &$login, &$senha) {
        $usuario = new Usuario();
        $usuario->setNome($nome);
        $usuario->setLogin($login);
        $usuario->setSenha($senha);
        $usuario->setGrupo($this);
        $usuario->cadastrar();
        $this->usuarios[$usuario->getCod_usuario()] = &$usuario;
    }

    public function alterarUsuario(&$cod_usuario, &$campo_id, &$campo_valor) {
        $usuario = $this->usuarios[$cod_usuario];
        if (!$usuario instanceof Usuario) {
            throw new Exception("Usuário inexistente");
        }
        $usuario->alterarCampo($campo_id, $campo_valor);
        $this->usuarios[$i] = &$usuario;
    }

    /**
     *
     * @param <type> $cod_usuario
     * @return Usuario 
     */
    public function getUsuario(&$cod_usuario) {
        $usuario = &$this->usuarios[$cod_usuario];
        if (!$usuario instanceof Usuario) {
            throw new Exception("Usuário inexistente");
        }
        return $usuario;
    }

    public function excluirUsuario(&$cod_usuario) {
        $usuario = &$this->usuarios[$cod_usuario];
        ;
        if (!$usuario instanceof Usuario) {
            throw new Exception("Usuário inexistente");
        }
        $usuario->excluir();
        unset($this->usuarios[$cod_usuario]);
    }

    public function cadastrarPermissao(&$consulta, &$inclusao, &$alteracao, &$exclusao, &$recurso) {
        $permissao = new Permissao();
        $permissao->setAlteracao($alteracao);
        $permissao->setConsulta($consulta);
        $permissao->setExclusao($exclusao);
        $permissao->setGrupo($this);
        $permissao->setInclusao($inclusao);
        $permissao->setRecurso($recurso);
        $permissao->cadastrar();
        $this->permissoes[$permissao->getCod_permissao()] = &$permissao;
    }

    public function alterarPermissao(&$cod_permissao, &$campo_id, &$campo_valor) {
        $permissao = $this->permissoes[$cod_permissao];
        if (!$permissao instanceof Permissao) {
            throw new Exception("Permissão inexistente");
        }
        $permissao->alterarCampo($campo_id, $campo_valor);
        $this->permissoes[$cod_permissao] = &$permissao;
    }

    /**
     *
     * @param <type> $cod_permissao
     * @return Permissao 
     */
    public function getPermissao(&$recurso) {
        foreach ($this->permissoes as $permissao) {
            if ($permissao->isRecurso($recurso)) {
                return $permissao;
            }
        }
        return null;
    }

    public function excluirPermissao(&$cod_permissao) {
        $permissao = &$this->permissoes[$cod_permissao];
        if (!$permissao instanceof Permissao) {
            throw new Exception("Permissão inexistente");
        }
        $permissao->excluir();
        unset($this->permissoes[$cod_permissao]);
    }

}
?>